import { pick, unset } from 'lodash';
import { CustomRepositoryDecorator } from 'src/database/decorator/repository.decorator';

import { FindOptionsUtils, FindTreeOptions, TreeRepository } from 'typeorm';
import { CategoryEntity } from '../Entity';



@CustomRepositoryDecorator(CategoryEntity)
export class CategoryRepository extends TreeRepository<CategoryEntity> {
    /**
     * 构建基础查询器
     */
    buildBaseQB() {
        return this.createQueryBuilder('category')
            .leftJoinAndSelect('category.parent', 'parent')
    }

    /**
     * 查询树形分类
     * @param options 数据类型是  FindTreeOptions 意思就是数据查询的where id 之类的
     * @param findRoots  获取所有根节点
     * @param   findDescendantsTree  所有后代节点（即子孙节点），并返回一个嵌套结构的树形数组，
     */
    async findTree(option?: FindTreeOptions) {
        let roots = await this.findRoots(option)
        await Promise.all(roots.map(root => {
            return this.findDescendantsTree(root, option)
        }))
    }
    /**
     * 查询顶级分类
     * @param options
     */
    findRoots(option: FindTreeOptions) {
        //防止被sqL注入
        const escapeAlias = (alis: string) => this.manager.connection.driver.escape(alis)
        const escapeColumn = (column: string) => this.manager.connection.driver.escape(column)


        const joinColumn = this.metadata.treeParentRelation!.joinColumns[0]
        const parentPropertyName = joinColumn.givenDatabaseName || joinColumn.databaseName
        let qb = this.buildBaseQB().orderBy('category.customOrder', 'ASC')
        qb.where(`${escapeAlias('category')}.${escapeColumn(parentPropertyName)} IS NULL`);
        return qb.getMany()
    }

    /**
     * 查询后代元素
     * @param entity
     * @param options
     */
    async findDescendant(entity: CategoryEntity, option?: FindTreeOptions) {

        //构造基础查询器
        let qb = this.createDescendantsQueryBuilder('category', 'treeClosure', entity)
        // 是 TypeORM 提供的一个帮助函数，用于将查询选项应用于树形结构查询的查询构建器
        FindOptionsUtils.applyOptionsToTreeQueryBuilder(qb, option)
        qb.orderBy('category.customOrder', 'ASC')
        return qb.getMany()

    }

    //在服装 男装  衬衫 中  男装和服装是 祖先元素 ，服装是顶级分类

    //数据扁平化
    async flattenCategoryTree(tree: CategoryEntity[], depth: number = 1, parent: CategoryEntity | null = null) {
        //定义接收的数组
        const flatTree: Omit<CategoryEntity, 'children' | 'hasId' | 'save' | 'remove' | 'softRemove' | 'recover' | 'reload'>[] = [];

        //对数据进行循环遍历
        for (const node of tree) {
            // 将当前节点的深度和父节点属性设置好
            node.depth = depth;
            node.parent = parent;

            // 将当前节点添加到扁平化数组中
            const flatNode = { ...node };
            delete flatNode.children;
            flatTree.push(flatNode);
            //对函数进行递归
            if (flatNode.children.length != 0) {
                let flattenedChildren: any = await this.flattenCategoryTree(node.children, depth + 1, node);
                flatTree.push(...flattenedChildren);
            }
            return flatTree
        }

    }




}
